package com.sanjin.configuration.security;

import com.sanjin.filter.JwtAuthenticationAdminFilter;
import com.sanjin.filter.JwtAuthenticationWxMiniUserFilter;
import com.sanjin.service.impl.AdminDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @description:        spring security 配置类
 * @author: sanjin
 * @date: 2019/5/4 19:47
 */

/**
 prePostEnabled :决定Spring Security的前注解是否可用 [@PreAuthorize,@PostAuthorize,..]
 secureEnabled : 决定是否Spring Security的保障注解 [@Secured] 是否可用
 jsr250Enabled ：决定 JSR-250 annotations 注解[@RolesAllowed..] 是否可用.
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Autowired
    JwtAuthenticationAdminFilter jwtAuthenticationAdminFilter;

    @Autowired
    JwtAuthenticationWxMiniUserFilter jwtAuthenticationWxMiniUserFilter;

    @Autowired
    AdminDetailsService adminDetailsService;


    @Bean
    AuthenticationManager getAuthenticationManager() throws Exception {
//        new ProviderManager()
        return super.authenticationManager();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // swagger config
        web.ignoring().antMatchers("/swagger-ui.html")
                .antMatchers("/webjars/**")
                .antMatchers("/v2/**")
                .antMatchers("/swagger-resources/**");
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return new PlaintextPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // auth.userDetailsService(adminDetailsService).passwordEncoder(new PlaintextPasswordEncoder());
        super.configure(auth);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .exceptionHandling()
                // 权限异常处理
                .accessDeniedHandler(new AuthorizationAccessDeniedHandler())
                // 认证异常处理
                .authenticationEntryPoint(new JwtAuthenticationEntryPoint())

                .and()

                .authorizeRequests()
                // 不进行认证
                // .antMatchers("/**").permitAll()

                // cros 预请求不进行拦截
                .antMatchers(HttpMethod.OPTIONS).permitAll()

                // 开放登陆接口
                .antMatchers("/auth/**").permitAll()
                // 开放摄像头所需接口
                .antMatchers("/shexiangtou/**").permitAll()

                // 剩余请求需要认证
                .anyRequest().authenticated()


                .and()

                // 禁用session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                // 禁用 csrf
                .csrf().disable()
                // 添加过滤器
                .addFilterBefore(jwtAuthenticationAdminFilter,UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(jwtAuthenticationWxMiniUserFilter,UsernamePasswordAuthenticationFilter.class)
                // header进行缓存
                .headers().cacheControl();
    }
}
